/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package xdxn.editor.studio.gui.barrage;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;
import xdxn.editor.studio.biz.barrage.BarrageTableModel;
import xdxn.editor.studio.biz.barrage.MuzzleTableModel;
import xdxn.editor.studio.data.Project;
import xdxn.editor.studio.data.ProjectManager;
import xdxn.editor.studio.data.barrage.Barrage;
import xdxn.editor.studio.data.barrage.Muzzle;
import xdxn.editor.studio.geom.Rect2D;

/**
 *
 * @author Cai Han
 */
public class BarrageMainWindow extends JFrame {

    private final BarrageMainWindow _barrageMainWindow = this;
    private final Project _project;

    /**
     * Creates new form EjectorMainWindow
     *
     * @param projectName 项目名称
     */
    public BarrageMainWindow( String projectName ) {
        _project = ProjectManager.getInstance().create(projectName);
        _project.initBarrageData();
        _barrageTableModel = new BarrageTableModel(_project.barrage_list);
        _muzzleTableModel = new MuzzleTableModel(null);
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings( "unchecked" )
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        splitPane1 = new javax.swing.JSplitPane();
        _left_container = new javax.swing.JPanel();
        mComponentPanel = new javax.swing.JPanel();
        _btn_create_barrage = new javax.swing.JButton();
        _btn_create_muzzle = new javax.swing.JButton();
        _btn_copy_barrage = new javax.swing.JButton();
        _btn_delete_barrage = new javax.swing.JButton();
        _btn_copy_muzzle = new javax.swing.JButton();
        _btn_delete_muzzle = new javax.swing.JButton();
        jSplitPane1 = new javax.swing.JSplitPane();
        _barrage_list_container = new javax.swing.JPanel();
        _scroll_pane_container = new javax.swing.JScrollPane();
        _barrage_table = new javax.swing.JTable();
        _muzzle_list_container = new javax.swing.JPanel();
        _scroll_pane_container1 = new javax.swing.JScrollPane();
        _muzzle_table = new javax.swing.JTable();
        jPanel2 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jSlider1 = new javax.swing.JSlider();
        _right_container = new javax.swing.JPanel();
        _container = new javax.swing.JPanel();

        setTitle("弹幕编辑器");
        setMinimumSize(new java.awt.Dimension(800, 800));
        setPreferredSize(new java.awt.Dimension(800, 800));

        splitPane1.setDividerLocation(250);
        splitPane1.setDividerSize(1);
        splitPane1.setEnabled(false);

        _left_container.setMaximumSize(new java.awt.Dimension(200, 2147483647));
        _left_container.setMinimumSize(new java.awt.Dimension(200, 100));
        _left_container.setPreferredSize(new java.awt.Dimension(200, 573));
        _left_container.setLayout(new java.awt.BorderLayout());

        mComponentPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)), "组件操作区", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));

        _btn_create_barrage.setText("创建弹幕");
        _btn_create_barrage.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                _btn_create_barrageActionPerformed(evt);
            }
        });

        _btn_create_muzzle.setText("创建炮口");
        _btn_create_muzzle.setEnabled(false);
        _btn_create_muzzle.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                _btn_create_muzzleActionPerformed(evt);
            }
        });

        _btn_copy_barrage.setText("复制弹幕");
        _btn_copy_barrage.setEnabled(false);
        _btn_copy_barrage.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                _btn_copy_barrageActionPerformed(evt);
            }
        });

        _btn_delete_barrage.setText("删除弹幕");
        _btn_delete_barrage.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                _btn_delete_barrageActionPerformed(evt);
            }
        });

        _btn_copy_muzzle.setText("复制炮口");
        _btn_copy_muzzle.setEnabled(false);

        _btn_delete_muzzle.setText("删除炮口");
        _btn_delete_muzzle.setEnabled(false);

        javax.swing.GroupLayout mComponentPanelLayout = new javax.swing.GroupLayout(mComponentPanel);
        mComponentPanel.setLayout(mComponentPanelLayout);
        mComponentPanelLayout.setHorizontalGroup(
            mComponentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mComponentPanelLayout.createSequentialGroup()
                .addGap(22, 22, 22)
                .addGroup(mComponentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(mComponentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                        .addComponent(_btn_copy_barrage)
                        .addComponent(_btn_create_barrage))
                    .addComponent(_btn_delete_barrage))
                .addGap(23, 23, 23)
                .addGroup(mComponentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(_btn_create_muzzle)
                    .addComponent(_btn_copy_muzzle)
                    .addComponent(_btn_delete_muzzle))
                .addContainerGap(22, Short.MAX_VALUE))
        );
        mComponentPanelLayout.setVerticalGroup(
            mComponentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mComponentPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mComponentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(_btn_create_muzzle)
                    .addComponent(_btn_create_barrage))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mComponentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(_btn_copy_barrage)
                    .addComponent(_btn_copy_muzzle))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mComponentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(_btn_delete_barrage)
                    .addComponent(_btn_delete_muzzle))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        _left_container.add(mComponentPanel, java.awt.BorderLayout.PAGE_START);

        jSplitPane1.setDividerLocation(200);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

        _barrage_list_container.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)), "弹幕列表", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        _barrage_list_container.setLayout(new java.awt.BorderLayout());

        _barrage_table.setModel(_barrageTableModel);
        _barrage_table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        _barrage_table.getTableHeader().setResizingAllowed(false);
        _barrage_table.getTableHeader().setReorderingAllowed(false);
        _barrage_table.setAutoscrolls(true);
        _barrage_table.getColumn(_barrageTableModel.getColumnName(0)).setMaxWidth(40);
        _scroll_pane_container.setViewportView(_barrage_table);
        _barrage_table.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);

        _barrage_list_container.add(_scroll_pane_container, java.awt.BorderLayout.CENTER);

        jSplitPane1.setLeftComponent(_barrage_list_container);

        _muzzle_list_container.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)), "炮口列表", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        _muzzle_list_container.setLayout(new java.awt.BorderLayout());

        _muzzle_table.setModel(_muzzleTableModel);
        _muzzle_table.getColumn(_muzzleTableModel.getColumnName(0)).setMaxWidth(40);
        _scroll_pane_container1.setViewportView(_muzzle_table);

        _muzzle_list_container.add(_scroll_pane_container1, java.awt.BorderLayout.CENTER);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)), "控制区", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        jPanel2.setPreferredSize(new java.awt.Dimension(599, 62));

        jButton1.setText("开始");

        jSlider1.setPaintLabels(true);
        jSlider1.setPaintTicks(true);
        jSlider1.setValue(0);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGap(6, 6, 6)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSlider1, javax.swing.GroupLayout.DEFAULT_SIZE, 143, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGap(3, 3, 3)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        _muzzle_list_container.add(jPanel2, java.awt.BorderLayout.PAGE_END);

        jSplitPane1.setRightComponent(_muzzle_list_container);

        _left_container.add(jSplitPane1, java.awt.BorderLayout.CENTER);

        splitPane1.setLeftComponent(_left_container);

        _right_container.setLayout(new java.awt.BorderLayout());

        _container.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)), "编辑区", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        _container.setLayout(new java.awt.BorderLayout());
        _barragePerformancePanel = new BarragePerformancePanel();
        _container.add(_barragePerformancePanel);
        _right_container.add(_container, java.awt.BorderLayout.CENTER);

        splitPane1.setRightComponent(_right_container);

        getContentPane().add(splitPane1, java.awt.BorderLayout.CENTER);

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>//GEN-END:initComponents

    /**
     * 创建弹幕
     */
    private void _btn_create_barrageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__btn_create_barrageActionPerformed
        // 添加到显示列表
        Barrage barrage = this._barrageTableModel.add(-1);
        // 设置当前列表选择
        int selectedIndex = this._barrageTableModel.getRowCount() - 1;
        this._barrage_table.setRowSelectionInterval(selectedIndex , selectedIndex);
        this._barrage_table.updateUI();
        // 设置炮口列表的list对象
        this._muzzleTableModel.setList(barrage.muzzle_list);
        // 开启一些按钮
        this._btn_copy_barrage.setEnabled(true);
        this._btn_create_muzzle.setEnabled(true);
        this._btn_delete_barrage.setEnabled(true);
        // 展示面板进行展示
        this._barragePerformancePanel.current_barrage = barrage;
        this._barragePerformancePanel.repaint();
    }//GEN-LAST:event__btn_create_barrageActionPerformed

    /**
     * 删除弹幕
     */
    private void _btn_delete_barrageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__btn_delete_barrageActionPerformed
        int selectedIndex = this._barrage_table.getSelectedRow();
        this._barrageTableModel.remove(selectedIndex);
    }//GEN-LAST:event__btn_delete_barrageActionPerformed

    /**
     * 创建炮口
     */
    private void _btn_create_muzzleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__btn_create_muzzleActionPerformed
        // TODO add your handling code here:
        Muzzle muzzle = this._muzzleTableModel.add(-1);
        // 
        muzzle.x = this._barragePerformancePanel.getWidth() / 2;
        muzzle.y = this._barragePerformancePanel.getHeight() / 2;
        // 
        int selectedIndex = this._muzzle_table.getRowCount() - 1;
        this._muzzle_table.setRowSelectionInterval(selectedIndex , selectedIndex);
        // 开启一些按钮
        this._btn_copy_muzzle.setEnabled(true);
        this._btn_delete_muzzle.setEnabled(true);
        // 
        this._barragePerformancePanel.repaint();
    }//GEN-LAST:event__btn_create_muzzleActionPerformed

    /**
     * 创建弹幕
     */
    private void _btn_copy_barrageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__btn_copy_barrageActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event__btn_copy_barrageActionPerformed

    private final BarrageTableModel _barrageTableModel;
    private final MuzzleTableModel _muzzleTableModel;

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel _barrage_list_container;
    private javax.swing.JTable _barrage_table;
    private javax.swing.JButton _btn_copy_barrage;
    private javax.swing.JButton _btn_copy_muzzle;
    private javax.swing.JButton _btn_create_barrage;
    private javax.swing.JButton _btn_create_muzzle;
    private javax.swing.JButton _btn_delete_barrage;
    private javax.swing.JButton _btn_delete_muzzle;
    private javax.swing.JPanel _container;
    private javax.swing.JPanel _left_container;
    private javax.swing.JPanel _muzzle_list_container;
    private javax.swing.JTable _muzzle_table;
    private javax.swing.JPanel _right_container;
    private javax.swing.JScrollPane _scroll_pane_container;
    private javax.swing.JScrollPane _scroll_pane_container1;
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JSlider jSlider1;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JPanel mComponentPanel;
    private javax.swing.JSplitPane splitPane1;
    // End of variables declaration//GEN-END:variables

    private BarragePerformancePanel _barragePerformancePanel;

    /**
     * 展示类
     */
    private class BarragePerformancePanel extends JPanel {

        private final BarragePerformancePanel _panel = this;
        /**
         * 当前操作的弹幕对象
         */
        private Barrage current_barrage;

        public BarragePerformancePanel() {
            this.addMouseListener(this._mouseListener);
            this.addMouseMotionListener(this._mouseMotionAdapter);
        }

        @Override
        public void paint( Graphics g ) {
            // 清理绘制区，底层好像没有清理，但是还是达到了效果，这里再清理一次
            g.clearRect(0 , 0 , this.getWidth() , this.getHeight());
            // 绘制底部背景
            g.setColor(Color.BLACK);
            g.fillRect(0 , 0 , this.getWidth() , this.getHeight());
            // 判断当前有没有弹幕
            if ( null != current_barrage ) {
                Muzzle temp_muzzle;
                for ( int i = current_barrage.muzzle_list.size() - 1 ; i >= 0 ; i-- ) {
                    temp_muzzle = current_barrage.muzzle_list.get(i);
                    // 判断是否是当前选择的对象，区别绘制
                    if ( temp_muzzle == current_barrage.current_muzzle ) {
                        drawMuzzle(g , temp_muzzle , Color.RED);
                    } else {
                        drawMuzzle(g , temp_muzzle , Color.WHITE);
                    }
                }
            }
        }

        // 绘制炮口
        private void drawMuzzle( Graphics g , Muzzle muzzle , Color color ) {
            g.setColor(color);
            g.drawArc(muzzle.x - Muzzle.DISPLAY_WIDTH / 2 ,
                      muzzle.y - Muzzle.DISPLAY_HEIGHT / 2 ,
                      Muzzle.DISPLAY_WIDTH ,
                      Muzzle.DISPLAY_HEIGHT ,
                      0 ,
                      360);
            String id = "id:" + muzzle.id;
            int charWidth = g.getFontMetrics().charWidth('a') - 1;
            g.drawString( id,
                         muzzle.x  - (id.length() * charWidth) / 2,
                         muzzle.y - 2 - Muzzle.DISPLAY_HEIGHT / 2);
        }

        private int _mouseX;
        private int _mouseY;

        private int _dragX;
        private int _dragY;

        private final MouseMotionAdapter _mouseMotionAdapter = new MouseMotionAdapter() {
            @Override
            public void mouseDragged( MouseEvent e ) {
                //
                _dragX = e.getX();
                _dragY = e.getY();
                // 判断当前的炮口对象是否为空
                if ( current_barrage.current_muzzle != null ) {
                    // 不为空的话计算移动品偏移
                    int deltaX = _dragX - _mouseX;
                    int deltaY = _dragY - _mouseY;
                    // 
                    _mouseX = _dragX;
                    _mouseY = _dragY;
                    // 改变坐标
                    current_barrage.current_muzzle.x += deltaX;
                    current_barrage.current_muzzle.y += deltaY;
                }

                _panel.repaint();
            }

            @Override
            public void mouseMoved( MouseEvent e ) {
                //
                _mouseX = e.getX();
                _mouseY = e.getY();
            }
        };

        private final MouseListener _mouseListener = new MouseListener() {
            @Override
            public void mouseClicked( MouseEvent e ) {
                // 无对象不做处理
                if ( current_barrage == null ) {
                    return;
                }
                //
                _mouseX = e.getX();
                _mouseY = e.getY();
                // 获取当前点击坐标上的炮口
                current_barrage.current_muzzle = getMuzzle(_mouseX , _mouseY);
                updateUIForMuzzle();
                // 判断双击
                if ( e.getClickCount() == 2 ) {

                    if ( current_barrage.current_muzzle == null ) {
                        return;
                    }

                    BarrageProperty b = new BarrageProperty(_barrageMainWindow , current_barrage.current_muzzle);
                    b.setVisible(true);
                    _barrageMainWindow.setEnabled(false);
                }
            }

            @Override
            public void mousePressed( MouseEvent e ) {
                //
                _mouseX = e.getX();
                _mouseY = e.getY();
                // 获取当前点击坐标上的炮口
                current_barrage.current_muzzle = getMuzzle(_mouseX , _mouseY);
                updateUIForMuzzle();
                _panel.repaint();
            }

            @Override
            public void mouseReleased( MouseEvent e ) {
                //
                _mouseX = e.getX();
                _mouseY = e.getY();
            }

            @Override
            public void mouseEntered( MouseEvent e ) {
            }

            @Override
            public void mouseExited( MouseEvent e ) {
            }

        };

        /**
         * 通过炮口在编辑区的坐标获取炮口对象
         *
         * @param x 传入的炮口X坐标
         * @param y 传入的炮口Y坐标
         * @return 返回炮口对象
         */
        public Muzzle getMuzzle( int x , int y ) {
            Rect2D rectangle;
            for ( Muzzle muzzle : current_barrage.muzzle_list ) {
                rectangle = new Rect2D(muzzle.x - Muzzle.DISPLAY_WIDTH / 2 ,
                                          muzzle.y - Muzzle.DISPLAY_HEIGHT / 2 ,
                                          Muzzle.DISPLAY_WIDTH ,
                                          Muzzle.DISPLAY_HEIGHT);
                if ( rectangle.contains(x , y) ) {
                    return muzzle;
                }
            }
            return null;
        }

        /**
         * 针对选择炮口更新一些UI
         */
        private void updateUIForMuzzle() {
            // 如果当前炮口为空，应该通知界外面屏蔽一些按键
            if ( null == current_barrage.current_muzzle ) {
                _btn_copy_muzzle.setEnabled(false);
                _btn_delete_muzzle.setEnabled(false);
                _muzzle_table.clearSelection();
            } else {
                _btn_copy_muzzle.setEnabled(true);
                _btn_delete_muzzle.setEnabled(true);
                // 更新表格的行
                int index = current_barrage.muzzle_list.indexOf(current_barrage.current_muzzle);
                _muzzle_table.setRowSelectionInterval(index , index);
            }
        }
    }

}
